iT邦幫忙

2025 iThome 鐵人賽

DAY 26
0
佛心分享-SideProject30

從零開始改善工作之 Chrome Extension: MR 通知文字小工具系列 第 26

Day 26:延伸應用 — 結合 Shortcut(快捷鍵)

  • 分享至 

  • xImage
  •  

有時候當我們雙手放在鍵盤上就想要完成所有 MR 發文的話,這時候就會需要各種好用的快捷鍵!
例如:

  • 一鍵複製 MR 模板
  • 一鍵產生通知內容
  • 一鍵打開特定設定頁面

網頁沒有提供的話,我們就用 Chrome 提供的 Commands API 來自己寫吧!

HOW

background 接到快捷鍵 → 傳給目前分頁的 content script → 執行 MR 文字複製動作。

實作

  1. 在 manifest.json 中定義快捷鍵

    {
    ...,
      "commands": {
        "copy_mr_template": {
          "suggested_key": {
            "default": "Ctrl+Shift+Y",
            "mac": "Command+Shift+Y"
          },
          "description": "快速複製 MR 通知模板"
        }
      }
    

    說明:

    • commands: 用來定義所有快捷鍵。
    • suggested_key: 可以指定 Windows 與 macOS 不同的預設組合。
    • description: 會出現在使用者設定介面中。
  2. 在 background.js 中接收快捷鍵事件

    //background.js
     chrome.commands.onCommand.addListener((command) => {
       if (command === "copy_mr_template") {
         chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
           chrome.tabs.sendMessage(tabs[0].id, { action: "copyMRText" });
         });
       }
     });
    

    說明:

    • chrome.commands.onCommand.addListener 是監聽快捷鍵事件的主要 API。
    • 通常搭配 chrome.tabs.sendMessage() 傳送指令給 content script 處理實際邏輯。
  3. 在 content script 中將共用的複製功能提出,並回應快捷鍵事件

    //content_script.js
    async function onclick() {
     // 取得 MR 資料
     const titleEl = document.querySelector(".title")
         || document.querySelector("[data-testid='title-content']")
         || document.querySelector("h1");
     const reviewerEl = document.querySelector("[data-testid='reviewer'] div");
     const title = titleEl.innerText.trim()
     const reviewer = reviewerEl?.innerText.trim() || ''
     const clipboardItem = await generateReviewContent(title, reviewer);
     return clipboardItem
    }
    
    async function addCopyBtn() {
    ...
     // 監聽按鈕點擊事件
     btn.addEventListener('click', async () => {
         const clipboardItem = await onclick()
    
         // 複製文字到剪貼簿
         navigator.clipboard.write([clipboardItem]).then(() => {
             showToast("✅ 已成功複製通知文字!");
         }).catch(() => {
             showToast("❌ 複製失敗,請再試一次");
         });
     });
     ...
    }
    
     chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
         if (request.action === "copyMRText") {
             // 要檢查 focus
             if (!document.hasFocus()) {
                 showToast('請先切回該分頁再按快捷鍵');
                 return;
             }
             const clipboardItem = await onclick()
             // 複製文字到剪貼簿
             navigator.clipboard.write([clipboardItem]).then(() => {
                 showToast("✅ 已成功複製通知文字!");
             }).catch((err) => {
                 console.log(err);
    
                 showToast("❌ 複製失敗,請再試一次");
             });
         }
     });
    

    說明:

    如果沒有 focus 會發生錯誤 Uncaught (in promise) NotAllowedError: Failed to execute 'writeText' on 'Clipboard': Document is not focused.
    這是是 Clipboard API 的一個安全限制觸發,意思是:「網頁沒有焦點(not focused),所以瀏覽器拒絕執行 navigator.clipboard.writeText()」。

    在 Chrome、Edge、Firefox 等瀏覽器中:

    只有「目前使用者實際正在操作的分頁」才有權限寫入剪貼簿。

    • 如果 content_script 執行的頁面 不是目前使用者正看到的 tab
    • 頁面是 被 background 或 popup 呼叫、但實際沒 focus 的頁面

    就會被瀏覽器判定「不是使用者觸發的操作」,從而拒絕。

    因此要檢查 focus 並提醒使用者需要在開頁面上才能使用此按鈕

  4. 使用者自訂快捷鍵
    用戶可以在 Chrome 中輸入以下網址來自訂快捷鍵組合或停用特定快捷鍵:

    chrome://extensions/shortcuts
    

進階應用

  • manifest.json 中可以設多個 command,例如:
    "commands": {
      "copy_mr_template": {...},
      "open_popup": {...},
      "toggle_theme": {...}
    }
    
  • 搭配 chrome.action.openPopup() 讓快捷鍵自動開啟 popup。

Note

  • 不要用與系統快捷鍵衝突的組合(如 Ctrl+C、Ctrl+T)。
  • 在 popup 中提示使用者可用的快捷鍵,讓功能更容易被發現。
  • 若功能影響頁面內容(例如修改 DOM),請提醒使用者 extension 權限與動作內容。

參考來源


上一篇
Day 25:延伸應用 — 自動檢查 MR 描述格式
下一篇
Day 27:效能思考 — Content Script 何時注入最好?
系列文
從零開始改善工作之 Chrome Extension: MR 通知文字小工具27
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言